package basic.datastruct.队列;

import java.util.concurrent.*;

/**
 * @创建人 MBY381
 * @创建时间 2022/4/22 18:34
 * @描述  ArrayBlockingQueue内部未固定大小的数组，使用俩指针指定头尾，循环遍历
 */
public class BlockQueueTest {
    public static void main(String[] args) throws InterruptedException {
        test();
    }

    public static void test() throws InterruptedException {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(8); //初始需指定大小
        queue.add(1);
        queue.add(2);
        queue.add(3);
        queue.add(4);
        queue.add(5);
        queue.add(6);
        queue.add(7);
        queue.add(8);
        System.out.println(queue);
//        System.out.println(queue.add(1)); //报错，不可添加
        BlockingQueue<Integer> queue1=new LinkedBlockingDeque<>();

        BlockingQueue<MyDelayedTask> queue2= new DelayQueue<>();
        queue2.add(new MyDelayedTask("mby",10000));
        queue2.add(new MyDelayedTask("zzq",10000));
        queue2.add(new MyDelayedTask("hxy",10000));
        System.out.println(queue2);
        Thread.sleep(1000);
//        System.out.println(Objects.requireNonNull(queue2.poll())); //直接报错，因为不可访问

        Thread.sleep(9000);
        System.out.println(queue2.poll());
    }

    /**
     * 　DelayQueue只能添加(offer/put/add)实现了Delayed接口的对象，意思是说我们不能想往DelayQueue里添加什么就添加什么
     *  不能添加int、也不能添加String进去，
     *  必须添加我们自己的实现了Delayed接口的类的对象
     */
    static class MyDelayedTask implements Delayed{

        private final String name ;
        private final long start = System.currentTimeMillis();
        private final long time ;

        public MyDelayedTask(String name,long time) {
            this.name = name;
            this.time = time;
        }

        /**
         * 需要实现的接口，获得延迟时间   用过期时间-当前时间
         * @param unit
         * @return
         */
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert((start+time) - System.currentTimeMillis(),TimeUnit.MILLISECONDS);
        }

        /**
         * 用于延迟队列内部比较排序   当前时间的延迟时间 - 比较对象的延迟时间
         * @param o
         * @return
         */
        @Override
        public int compareTo(Delayed o) {
            MyDelayedTask o1 = (MyDelayedTask) o;
            return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
        }

        @Override
        public String toString() {
            return "MyDelayedTask{" +
                    "name='" + name + '\'' +
                    ", time=" + time +
                    '}';
        }
    }
}
